package ai.hou.camera.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import androidx.core.content.ContextCompat;

import ai.hou.camera.R;

/**
 * 遮罩
 *
 * @author zhaoxiaolei
 * @date 2021/3/15 9:00
 */
public class MagicMaskView extends View {

    /**
     * 啥也没有
     */
    public static final int MASK_NONE = 0;
    /**
     * 自定义，即需要传入图像
     */
    public static final int MASK_CUSTOM = 1;
    /**
     * 身份证国徽面
     */
    public static final int MASK_ID_CARD_FRONT = 2;
    /**
     * 身份证人像面
     */
    public static final int MASK_ID_CARD_BACK = 3;
    /**
     * 标准卡：如银行卡等
     */
    public static final int MASK_STANDARD_CARD = 4;

    private int mMaskType;
    private Drawable mBgDrawable;
    private Drawable mDrawable;
    private Drawable mTipDrawable;
    private Rect mBgBounds;
    private Rect mBounds;
    private Rect mTipBounds;

    private int mCustomDrawableWidth;
    private int mCustomDrawableHeight;

    private Drawable maybeCustomDrawable;
    private int maybeCustomWidth;
    private int maybeCustomHeight;

    /**
     * 白内障功能
     */
    private boolean isCataract;
    private final Paint mPaint;
    private RectF rectF;
    private final float maskCorner;
    private int cataractColor;

    public MagicMaskView(Context context) {
        this(context, null);
    }

    public MagicMaskView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MagicMaskView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        maskCorner = getResources().getDimension(R.dimen.mask_corner);
        cataractColor = ContextCompat.getColor(context, R.color.cataract_color);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MagicMaskView);
        mMaskType = a.getInt(R.styleable.MagicMaskView_mmv_mask_type, MASK_NONE);
        if (mMaskType == MASK_CUSTOM) {
            maybeCustomDrawable = a.getDrawable(R.styleable.MagicMaskView_mmv_mask_drawable);
            maybeCustomWidth = a.getDimensionPixelOffset(R.styleable.MagicMaskView_mmv_mask_drawable_width, 0);
            maybeCustomHeight = a.getDimensionPixelOffset(R.styleable.MagicMaskView_mmv_mask_drawable_height, 0);
        }
        a.recycle();

        initDrawable();
    }

    private void initDrawable() {
        if (mMaskType == MASK_CUSTOM) {
            mDrawable = maybeCustomDrawable;
            mCustomDrawableWidth = maybeCustomWidth;
            mCustomDrawableHeight = maybeCustomHeight;
        }
        if (mMaskType == MASK_ID_CARD_FRONT || mMaskType == MASK_ID_CARD_BACK || mMaskType == MASK_STANDARD_CARD) {
            mBgDrawable = ContextCompat.getDrawable(getContext(), R.drawable.shape_mask_bg_drawable);
        } else {
            mBgDrawable = null;
        }

        if (mMaskType == MASK_ID_CARD_FRONT) {
            mDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_id_card_front);
            mTipDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_hint_align_id_card_front);
        } else if (mMaskType == MASK_ID_CARD_BACK) {
            mDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_id_card_back);
            mTipDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_hint_align_id_card_back);
        } else if (mMaskType == MASK_STANDARD_CARD) {
            mDrawable = null;
            mTipDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_hint_align_standard_card);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int marginHor = getResources().getDimensionPixelOffset(R.dimen.mask_bg_margin_hor);
        int marginVer = getResources().getDimensionPixelOffset(R.dimen.mask_bg_margin_ver);
        int tipPadding = getResources().getDimensionPixelOffset(R.dimen.mask_tip_padding);
        int drawableWidth = 0;
        int drawableHeight = 0;
        if (mDrawable != null) {
            drawableWidth = mDrawable.getIntrinsicWidth();
            drawableHeight = mDrawable.getIntrinsicHeight();
        }
        int tipWidth = 0;
        int tipHeight = 0;
        if (mTipDrawable != null) {
            tipWidth = mTipDrawable.getIntrinsicWidth();
            tipHeight = mTipDrawable.getIntrinsicHeight();
        }

        if (mMaskType == MASK_ID_CARD_FRONT) {
            //85.6:54
            int height = (int) ((w - marginHor * 2) * 54 / 85.6f);
            mBgBounds = new Rect(marginHor, marginVer, w - marginHor, marginVer + height);
            //1:16.5
            int marginIdCardFront = (int) (mBgBounds.width() / 16.5f);
            //1:5
            int marginIdCardSize = mBgBounds.width() / 5;
            mBounds = new Rect(mBgBounds.left + marginIdCardFront,
                    mBgBounds.top + marginIdCardFront,
                    mBgBounds.left + marginIdCardFront + marginIdCardSize,
                    mBgBounds.top + marginIdCardFront + marginIdCardSize * drawableHeight / drawableWidth);
            mTipBounds = new Rect(mBgBounds.left + (mBgBounds.width() - tipWidth) / 2,
                    mBgBounds.top - tipPadding - tipHeight,
                    mBgBounds.left + (mBgBounds.width() - tipWidth) / 2 + tipWidth,
                    mBgBounds.top - tipPadding);
        } else if (mMaskType == MASK_ID_CARD_BACK) {
            //85.6:54
            int height = (int) ((w - marginHor * 2) * 54 / 85.6f);
            mBgBounds = new Rect(marginHor, marginVer, w - marginHor, marginVer + height);
            //1:12.5
            int marginIdCardBack = (int) (mBgBounds.width() / 12.5f);
            //1:3.5
            int marginIdCardSize = (int) (mBgBounds.width() / 3.5f);
            int dHeight = marginIdCardSize * drawableHeight / drawableWidth;
            mBounds = new Rect(mBgBounds.right - marginIdCardBack - marginIdCardSize,
                    mBgBounds.top + (mBgBounds.height() - drawableHeight) * 4 / 9,
                    mBgBounds.right - marginIdCardBack,
                    mBgBounds.top + (mBgBounds.height() - dHeight) * 4 / 9 + dHeight);
            mTipBounds = new Rect(mBgBounds.left + (mBgBounds.width() - tipWidth) / 2,
                    mBgBounds.top - tipPadding - tipHeight,
                    mBgBounds.left + (mBgBounds.width() - tipWidth) / 2 + tipWidth,
                    mBgBounds.top - tipPadding);
        } else if (mMaskType == MASK_STANDARD_CARD) {
            //85.6:54
            int height = (int) ((w - marginHor * 2) * 54 / 85.6f);
            mBgBounds = new Rect(marginHor, marginVer, w - marginHor, marginVer + height);
            mTipBounds = new Rect(mBgBounds.left + (mBgBounds.width() - tipWidth) / 2,
                    mBgBounds.top - tipPadding - tipHeight,
                    mBgBounds.left + (mBgBounds.width() - tipWidth) / 2 + tipWidth,
                    mBgBounds.top - tipPadding);
        } else if (mMaskType == MASK_CUSTOM) {
            mCustomDrawableWidth = Math.min(mCustomDrawableWidth, w);
            mCustomDrawableHeight = Math.min(mCustomDrawableHeight, h);
            mBounds = new Rect((w - mCustomDrawableWidth) / 2,
                    marginVer,
                    (w - mCustomDrawableWidth) / 2 + mCustomDrawableWidth,
                    marginVer + mCustomDrawableHeight);
        }
        rectF = new RectF(mBgBounds);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mBgDrawable != null && !mBgBounds.isEmpty()) {
            if (isCataract) {
                canvas.drawColor(cataractColor);
                canvas.drawRoundRect(rectF, maskCorner, maskCorner, mPaint);
            }
            mBgDrawable.setBounds(mBgBounds);
            mBgDrawable.draw(canvas);
        }
        if (mBounds != null && !mBounds.isEmpty()) {
            mDrawable.setBounds(mBounds);
            mDrawable.draw(canvas);
        }
        if (mTipBounds != null && !mTipBounds.isEmpty()) {
            mTipDrawable.setBounds(mTipBounds);
            mTipDrawable.draw(canvas);
        }
    }

    public void setMaskType(int maskType) {
        this.mMaskType = maskType;
        initDrawable();
        requestLayout();
    }

    public void setCustomDrawable(Drawable customDrawable, int width, int height) {
        this.maybeCustomDrawable = customDrawable;
        this.maybeCustomWidth = width;
        this.maybeCustomHeight = height;
    }

    public Rect getBgBound() {
        return mBgBounds;
    }

    /**
     * 是否要白内障
     */
    public void setCataract(boolean cataract) {
        isCataract = cataract;
        invalidate();
    }

    public void setCataractColor(int cataractColor) {
        if (cataractColor == 0) {
            return;
        }
        this.cataractColor = cataractColor;
        invalidate();
    }
}
